package com.example.shiro.shiro.aspect;


import com.example.shiro.shiro.log.SystemLog;
import com.example.shiro.shiro.model.Log;
import com.example.shiro.shiro.model.SysUser;
import com.example.shiro.shiro.service.LogService;
import com.example.shiro.shiro.utils.RequestIP;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 日志切面类
 * Created by chong on 2020/4/3.
 */
@Aspect
@Component
public class SystemAspectLogger {
    private final Logger logger = LoggerFactory.getLogger(SystemAspectLogger.class);
    @Autowired
    private LogService logService;

    //标注该方法体为后置通知，当目标方法执行成功后执行该方法体
    @AfterReturning("@annotation(systemLog)")
    public void addLogSuccess(JoinPoint jp, SystemLog systemLog) {
        //是否记录日志
        if (systemLog.logFlag()) {
            createLogInfo(jp, systemLog, null);
        }
    }

    //标注该方法体为异常通知
    @AfterThrowing(pointcut = "@annotation(systemLog)", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, SystemLog systemLog, Throwable e) {
        //是否记录日志
        if (systemLog.logFlag()) {
            createLogInfo(joinPoint, systemLog, e);
        }
    }

    private void createLogInfo(JoinPoint jp, SystemLog systemLog, Throwable e) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            SysUser user = (SysUser) request.getSession().getAttribute("sessionKey");
            String ip = RequestIP.getIpAddr(request);
            /*操作日志实体类*/
            Log log = new Log();
            log.setModelName(systemLog.modelName());//模块名称
            log.setOperationName(systemLog.operationName());//操作名称
            log.setOperationType(systemLog.operationType().getDesc());//操作类型
            log.setOperationDesc(systemLog.desc());//操作描述
            String params = "";
            if (null != jp.getArgs()) {
                try {
//                    params = String.valueOf(JSONObject.toJSON(jp.getArgs()));
                } catch (Exception ex) {
                    params = "参数数据转JSON出现错误:" + ex.getMessage();
                }
            }
            log.setParams(params);//操作数据

            String className = String.valueOf(jp.getTarget().getClass());//获取目标类名
            log.setOperationClas(className.substring(className.indexOf("com")));//类

            String methodName = jp.getSignature().getName();//获取目标方法签名
            log.setMethod(methodName);//方法
            if (e != null) {
                log.setExceptionInfo(e.getMessage());//操作异常信息
            }
            if (user != null) {
                log.setUserName(user.getLoginName());//操作人
                log.setUserId(user.getUserId());//操作人id
            }
            log.setOperationIP(ip);//操作ip
            logService.insertLog(log);
        } catch (Exception e1) {
            logger.info("插入日志出错" + e1.getMessage());
        }
    }

}
